"""FastAPI application factory with global middleware and routers."""

from __future__ import annotations

from pathlib import Path

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles

from app.api.v1.api import api_router
from app.core.config import settings
from app.core.errors import http_exception_handler, server_error_handler, validation_exception_handler
from app.core.logger import app_logger
from app.ui import ui_router


def create_app() -> FastAPI:
    app = FastAPI(
        title=settings.APP_NAME,
        description="",
        version="1.0.0",
        openapi_url=f"{settings.API_V1_STR}/openapi.json",
        docs_url="/docs",
        redoc_url="/redoc",
        # Ensure response models serialize using field aliases (camelCase)
        response_model_by_alias=True,
        openapi_tags=[
            {"name": "auth", "description": "认证与授权"},
        ],
    )

    # Health check endpoint - simplified to avoid Content-Length errors
    @app.get("/health", tags=["health"])
    async def health_check():
        """健康检查端点 - 用于监控和负载均衡器探测."""
        return {"status": "healthy", "version": "1.0.0"}

    app.include_router(api_router, prefix=settings.API_V1_STR)
    app.include_router(ui_router)
    # Use absolute path to ensure correct resolution regardless of CWD
    app.mount(
        "/static",
        StaticFiles(directory=str(Path(__file__).resolve().parent.parent / "static")),
        name="static",
    )

    frontend_build_dir = Path(__file__).resolve().parents[3] / "frontend" / "build"
    if frontend_build_dir.exists():
        app_logger.info("Serving SvelteKit frontend from %s", frontend_build_dir)
        app.mount("/", StaticFiles(directory=str(frontend_build_dir), html=True), name="frontend")
    else:
        app_logger.warning("Frontend build directory not found at %s; SPA will not be served", frontend_build_dir)

    # CORS: 简单兼容处理, 不固定前端端口
    # 优先使用环境变量指定的允许来源; 否则允许任意 localhost/127.0.0.1 端口
    if settings.BACKEND_CORS_ORIGINS:
        # Convert AnyHttpUrl to string and remove trailing slash for exact matching
        origins = [str(o).rstrip("/") for o in settings.BACKEND_CORS_ORIGINS]
        app.add_middleware(
            CORSMiddleware,
            allow_origins=origins,
            allow_credentials=True,
            allow_methods=["*"],
            allow_headers=["*"],
        )
    else:
        app.add_middleware(
            CORSMiddleware,
            allow_origin_regex=r"^https?://(localhost|127\\.0\\.0\\.1)(:\\d+)?$",
            allow_credentials=True,
            allow_methods=["*"],
            allow_headers=["*"],
        )

    app.add_exception_handler(Exception, server_error_handler)
    from fastapi import HTTPException
    from fastapi.exceptions import RequestValidationError
    from starlette.exceptions import HTTPException as StarletteHTTPException

    app.add_exception_handler(HTTPException, http_exception_handler)  # type: ignore[arg-type]
    app.add_exception_handler(StarletteHTTPException, http_exception_handler)  # type: ignore[arg-type]
    app.add_exception_handler(RequestValidationError, validation_exception_handler)  # type: ignore[arg-type]

    return app
